home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / util / wxcopy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-29  |  5.3 KB  |  206 lines

  1. /* wxcopy.c- copy stdin or file into cutbuffer
  2.  * 
  3.  *  Copyright (c) 1997-1999 Alfredo K. Kojima
  4.  * 
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #define PROG_VERSION "wxcopy 0.3"
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <X11/Xlib.h>
  29. #include <X11/Xatom.h>
  30.  
  31.  
  32. #define LINESIZE    (4*1024)
  33. #define MAXDATA        (64*1024)
  34.  
  35. void
  36. help(char *progn)
  37. {
  38.     printf("Usage: %s [OPTIONS] [FILE]\n", progn);
  39.     puts("Copies data from FILE or stdin into X cut buffer.");
  40.     puts("");
  41.     puts("  -display <display>        display to use");
  42.     puts("  --cutbuffer <number>        cutbuffer number to put data");
  43.     puts("  --no-limit            do not limit size of input data");
  44.     puts("  --clear-selection        clears the current PRIMARY selection");
  45.     puts("  --help            display this help and exit");
  46.     puts("  --version            output version information and exit");
  47. }
  48.  
  49. static int
  50. errorHandler(Display *dpy, XErrorEvent *err)
  51. {
  52.     /* ignore all errors */
  53.     return 0;
  54. }
  55.  
  56.  
  57. int
  58. main(int argc, char **argv)
  59. {
  60.     Display *dpy;
  61.     int i;
  62.     int buffer=-1;
  63.     char *filename=NULL;
  64.     FILE *file=stdin;
  65.     char *buf=NULL;
  66.     char *display_name="";
  67.     int l=0;
  68.     int buf_len = 0;
  69.     int    limit_check = 1;
  70.     int clear_selection = 0;
  71.  
  72.     for (i=1; i<argc; i++) {
  73.     if (argv[i][0]=='-') {
  74.         if (strcmp(argv[i], "--help")==0) {
  75.         help(argv[0]);
  76.         exit(0);
  77.         } else if (strcmp(argv[i], "--version")==0) {
  78.         puts(PROG_VERSION);
  79.         exit(0);
  80.         } else if (strcmp(argv[i],"-cutbuffer")==0
  81.                || strcmp(argv[i],"--cutbuffer")==0) {
  82.         if (i<argc-1) {
  83.             i++;
  84.             if (sscanf(argv[i],"%i", &buffer)!=1) {
  85.             fprintf(stderr, "%s: could not convert '%s' to int\n", 
  86.                    argv[0], argv[i]);
  87.             exit(1);
  88.             }
  89.             if (buffer<0 || buffer > 7) {
  90.             fprintf(stderr, "%s: invalid buffer number %i\n",
  91.                 argv[0], buffer);
  92.             exit(1);
  93.             }
  94.         } else {
  95.             printf("%s: missing argument for '%s'\n", argv[0], argv[i]);
  96.             printf("Try '%s --help' for more information\n", argv[0]);
  97.             exit(1);
  98.         }
  99.         } else if (strcmp(argv[i], "-display")==0) {
  100.         if (i < argc-1) {
  101.             display_name = argv[++i];
  102.         } else {
  103.             printf("%s: missing argument for '%s'\n", argv[0], argv[i]);
  104.             printf("Try '%s --help' for more information\n", argv[0]);
  105.             exit(1);
  106.         }
  107.         } else if (strcmp(argv[i],"-clearselection")==0
  108.                || strcmp(argv[i],"--clear-selection")==0) {
  109.         clear_selection = 1;
  110.         } else if (strcmp(argv[i],"-nolimit")==0
  111.                || strcmp(argv[i],"--no-limit")==0) {
  112.         limit_check = 0;
  113.         } else {
  114.         printf("%s: invalid argument '%s'\n", argv[0], argv[i]);
  115.         printf("Try '%s --help' for more information\n", argv[0]);
  116.         exit(1);
  117.         }
  118.     } else {
  119.         filename = argv[i];
  120.     }
  121.     }
  122.     if (filename) {
  123.     file = fopen(filename, "r");
  124.     if (!file) {
  125.         char line[1024];
  126.         sprintf(line, "%s: could not open \"%s\"", argv[0], filename);
  127.         perror(line);
  128.         exit(1);
  129.     }
  130.     }
  131.  
  132.     dpy = XOpenDisplay(display_name);
  133.     XSetErrorHandler(errorHandler);
  134.     if (!dpy) {
  135.     fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
  136.         XDisplayName(display_name));
  137.     exit(1);
  138.     }
  139.     if (buffer<0) {
  140.     XRotateBuffers(dpy, 1);
  141.     buffer=0;
  142.     }
  143.     while (!feof(file)) {
  144.     char *nbuf;
  145.     char tmp[LINESIZE+2];
  146.     int nl=0;
  147.  
  148.     /*
  149.      * Use read() instead of fgets() to preserve NULs, since
  150.      * especially since there's no reason to read one line at a time.
  151.      */
  152.     if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
  153.         break;
  154.     }
  155.     if (buf_len == 0) {
  156.         nbuf = malloc(buf_len = l+nl+1);
  157.     }
  158.     else {
  159.         if (buf_len < l+nl+1) {
  160.         /*
  161.          * To avoid terrible performance on big input buffers,
  162.          * grow by doubling, not by the minimum needed for the
  163.          * current line.
  164.          */
  165.         buf_len = 2 * buf_len + nl + 1;
  166.         nbuf = realloc(buf, buf_len);
  167.         }
  168.         else {
  169.         nbuf = buf;
  170.         }
  171.     }
  172.     if (!nbuf) {
  173.         fprintf(stderr, "%s: out of memory\n", argv[0]);
  174.         exit(1);
  175.     }
  176.     buf=nbuf;
  177.     /*
  178.      * Don't strcat, since it would make the algorithm n-squared.
  179.      * Don't use strcpy, since it stops on a NUL.
  180.      */
  181.     memcpy(buf+l, tmp, nl);
  182.     l+=nl;
  183.     if (limit_check && l>=MAXDATA) {
  184.         fprintf
  185.         (
  186.         stderr,
  187.         "%s: too much data in input - more than %d bytes\n"
  188.         "  use the -nolimit argument to remove the limit check.\n",
  189.         argv[0], MAXDATA
  190.         );
  191.         exit(1);
  192.     }
  193.     }
  194.  
  195.     if (clear_selection) {
  196.     XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
  197.     }
  198.     if (buf) {
  199.     XStoreBuffer(dpy, buf, l, buffer);
  200.     }
  201.     XFlush(dpy);
  202.     XCloseDisplay(dpy);
  203.     exit(buf == NULL || errno != 0);
  204. }
  205.  
  206.